package com.ponhu.ea2.goodsCenter.provider.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ponhu.ea2.constants.CommonConstant;
import com.ponhu.ea2.constants.DictConstant;
import com.ponhu.ea2.dto.*;
import com.ponhu.ea2.entity.CloudTradeGoods;
import com.ponhu.ea2.entity.PhBrand;
import com.ponhu.ea2.entity.PhCategory;
import com.ponhu.ea2.entity.PhSysDictItem;
import com.ponhu.ea2.enums.ApplyCrowdEnum;
import com.ponhu.ea2.enums.GoodsStatusEnum;
import com.ponhu.ea2.enums.ResponseCodeEnum;
import com.ponhu.ea2.enums.SalesModelEnum;
import com.ponhu.ea2.goodsCenter.provider.biz.CloudTradeCoreService;
import com.ponhu.ea2.goodsCenter.provider.biz.OperationRecordLogsCoreService;
import com.ponhu.ea2.goodsCenter.provider.mapper.CloudTradeGoodsMapper;
import com.ponhu.ea2.goodsCenter.provider.mapper.MaterialMapper;
import com.ponhu.ea2.goodsCenter.provider.mapper.PhCategoryMapper;
import com.ponhu.ea2.goodsCenter.provider.service.*;
import com.ponhu.ea2.query.CloudTradeGoodsQuery;
import com.ponhu.ea2.support.exception.BusinessRuntimeException;
import com.ponhu.ea2.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

import static com.ponhu.ea2.constants.CommonConstant.BUSINESS_TYPE_CLOUD_TRADE;
import static com.ponhu.ea2.constants.CommonConstant.CLOUD_TRADE_GOODS_STATUS.NO_PASS;
import static com.ponhu.ea2.enums.ResponseCodeEnum.CLOUD_TRADE_GOODS_CHECKED_OVER_800103;
import static com.ponhu.ea2.enums.ResponseCodeEnum.CLOUD_TRADE_GOODS_UPDATE_STATUS_EXCEPTION_800101;

/**
 *
 */
@Slf4j
@Service
@RefreshScope
public class CloudTradeGoodsServiceImpl extends ServiceImpl<CloudTradeGoodsMapper, CloudTradeGoods>
        implements CloudTradeGoodsService {

    @Value("${third-party.cloud-trade.callback-check-result}")
    private String CLOUD_TRADE_CHECK_RESULT_URL;

    @Autowired
    private MaterialService materialService;
    @Autowired
    private PhSysDictItemService sysDictItemService;
    @Autowired
    private MaterialMapper materialMapper;
    @Autowired
    private PhBrandService brandService;
    @Autowired
    private PhCategoryService categoryService;
    @Autowired
    private PhCategoryMapper phCategoryMapper;
    @Autowired
    private CloudTradeCoreService cloudTradeCoreService;
    @Autowired
    private InventoryService inventoryService;
    @Autowired
    private OperationRecordLogsCoreService operationRecordLogsCoreService;

    @Deprecated
    @Override
    public CloudTradeGoodsDetailVO getCloudTradeGoodsDetailById(Long cloudTradeGoodsId) {
        CloudTradeGoods cloudTradeGoods = this.getById(cloudTradeGoodsId);
        if (cloudTradeGoods == null) {
            throw new BusinessRuntimeException(ResponseCodeEnum.CLOUD_TRADE_GOODS_NOT_EXISTS_800100);
        }

        CloudTradeGoodsDetailVO goodsDetailVO = new CloudTradeGoodsDetailVO();
        BeanUtils.copyProperties(cloudTradeGoods, goodsDetailVO);

        //图片设置
        if (StringUtils.isNotBlank(cloudTradeGoods.getDetailImage())) {
            goodsDetailVO.setDetailImages(Arrays.asList(cloudTradeGoods.getDetailImage().split("\\|")));
        }

        //货品属性设置
        if (StringUtils.isNotEmpty(cloudTradeGoods.getProperties())) {
            try {
                List<CloudTradeInventoryProperty> propertyList = JSONArray.parseArray(cloudTradeGoods.getProperties(), CloudTradeInventoryProperty.class);
                goodsDetailVO.setPropertyList(propertyList);
            } catch (Exception e) {
                //nothing to do
            }
        }

        //附件设置
        if (StringUtils.isNotEmpty(cloudTradeGoods.getAnnex())) {
            try {
                List<PhInventoryAccessoryVo> propertyList = JSONArray.parseArray(cloudTradeGoods.getAnnex(), PhInventoryAccessoryVo.class);
                goodsDetailVO.setAnnexList(propertyList);
            } catch (Exception e) {
                //nothing to do
            }
        }

        //配件属性设置
        if (StringUtils.isNotEmpty(cloudTradeGoods.getAccessory())) {
            try {
                List<PhInventoryAccessoryVo> propertyList = JSONArray.parseArray(cloudTradeGoods.getAccessory(), PhInventoryAccessoryVo.class);
                goodsDetailVO.setAccessoryList(propertyList);
            } catch (Exception e) {
                //nothing to do
            }
        }

        //物料信息设置
        if (StringUtils.isNotEmpty(cloudTradeGoods.getMaterialCode())) {
            PhMaterialVo materialVo = materialMapper.getMaterialVoByCode(cloudTradeGoods.getMaterialCode());

            if (materialVo != null) {
                goodsDetailVO.setPhMaterialVo(materialVo);
            }
        } else {
            //查询品牌与三级分类
            PhBrand brand = brandService.getById(cloudTradeGoods.getBrandId());
            if (brand != null) {
                goodsDetailVO.setBrandCnName(brand.getCnName()).setBrandEnName(brand.getEnName()).setBrandId(brand.getId());
            }

            PhCategory category = categoryService.getById(cloudTradeGoods.getCategoryId());
            if (category != null) {
                goodsDetailVO.setThirdCategoryId(category.getId()).setThirdCategoryName(category.getName());
            }
        }

        //成色设置
        CompletableFuture<Void> qualityFuture = CompletableFuture.runAsync(() -> {
            if (cloudTradeGoods.getQuality() != null) {
                PhSysDictItem item = sysDictItemService.getDictItemByValue(DictConstant.CONDITION_TYPE,
                        cloudTradeGoods.getQuality().toString());

                if (item != null) {
                    goodsDetailVO.setQuality(item.getLabel());
                }
            }
        });

        //入库方式设置
        CompletableFuture<Void> inWayFuture = CompletableFuture.runAsync(() -> {
            if (cloudTradeGoods.getInWay() != null) {
                PhSysDictItem item = sysDictItemService.getDictItemByValue(DictConstant.GOTOWARE_TYPE,
                        cloudTradeGoods.getInWay().toString());

                if (item != null) {
                    goodsDetailVO.setInWay(item.getLabel());
                }
            }
        });

        //货源设置
        CompletableFuture<Void> inventorySourceFuture = CompletableFuture.runAsync(() -> {
            if (cloudTradeGoods.getAccountId() != null) {
                PhSysDictItem item = sysDictItemService.getDictItemByValue(DictConstant.INVENTORY_SOURCE,
                        cloudTradeGoods.getAccountId().toString());

                if (item != null) {
                    goodsDetailVO.setInventorySource(item.getLabel());
                }
            }
        });

        CompletableFuture.allOf(qualityFuture, inWayFuture, inventorySourceFuture).join();
        return goodsDetailVO;
    }

    @Override
    public CloudTradeGoodsDetailV2VO getCloudTradeGoodsDetailByIdV2(Long cloudTradeGoodsId) {
        CloudTradeGoods cloudTradeGoods = this.getById(cloudTradeGoodsId);
        if (cloudTradeGoods == null) {
            throw new BusinessRuntimeException(ResponseCodeEnum.CLOUD_TRADE_GOODS_NOT_EXISTS_800100);
        }

        CloudTradeGoodsDetailV2VO goodsDetailVO = new CloudTradeGoodsDetailV2VO();
        BeanUtils.copyProperties(cloudTradeGoods, goodsDetailVO);

        //销售模式设置
        goodsDetailVO.setSalesModel(SalesModelEnum.getName(cloudTradeGoods.getSalesModel()));

        //适用人群
        goodsDetailVO.setApplyCrown(ApplyCrowdEnum.getName(cloudTradeGoods.getApplyCrowd()));

        //图片设置
        if (StringUtils.isNotBlank(cloudTradeGoods.getDetailImage())) {
            goodsDetailVO.setDetailImages(Arrays.asList(cloudTradeGoods.getDetailImage().split("\\|")));
        }

        //品牌设置
        PhBrand brand = brandService.getById(cloudTradeGoods.getBrandId());
        if (brand != null) {
            goodsDetailVO.setBrandCnName(brand.getCnName()).setBrandEnName(brand.getEnName()).setBrandId(brand.getId());
        }

        //品类设置
        PhCategoryLevel3Vo category = phCategoryMapper.getCategoryLevel3VosByThirdCategoryId(cloudTradeGoods.getCategoryId());
        if (category != null) {
            goodsDetailVO.setAllCategoryName(String.join("-",
                    Arrays.asList(category.getLevel1name(), category.getLevel2name(), category.getLevel3name())));
        }

        //货品属性设置
        if (StringUtils.isNotEmpty(cloudTradeGoods.getProperties())) {
            try {
                List<CloudTradePropertyDto> propertyList = JSONArray.parseArray(cloudTradeGoods.getProperties(), CloudTradePropertyDto.class);

                //从属性中拆解系列和型号
                if (CollectionUtils.isNotEmpty(propertyList)) {
                    propertyList.stream().filter(f -> "系列".equals(f.getName())).findFirst().ifPresent((i) -> goodsDetailVO.setSeriesName(i.getValue()));
                    propertyList.stream().filter(f -> "型号".equals(f.getName())).findFirst().ifPresent((i) -> goodsDetailVO.setModelName(i.getValue()));
                    goodsDetailVO.setPropertyList(propertyList.stream().filter(f -> !("系列".equals(f.getName()) || "型号".equals(f.getName()))).collect(Collectors.toList()));
                } else {
                    goodsDetailVO.setPropertyList(propertyList);
                }
            } catch (Exception e) {
                //nothing to do
            }
        }

        //附件设置
        if (StringUtils.isNotEmpty(cloudTradeGoods.getAnnex())) {
            try {
                List<String> propertyList = Arrays.asList(cloudTradeGoods.getAnnex().split(","));
                goodsDetailVO.setAnnexList(propertyList);
            } catch (Exception e) {
                //nothing to do
            }
        }

        //配件属性设置
        if (StringUtils.isNotEmpty(cloudTradeGoods.getAccessory())) {
            try {
                List<String> propertyList = Arrays.asList(cloudTradeGoods.getAccessory().split(","));
                goodsDetailVO.setAccessoryList(propertyList);
            } catch (Exception e) {
                //nothing to do
            }
        }

        //成色设置
        CompletableFuture<Void> qualityFuture = CompletableFuture.runAsync(() -> {
            if (cloudTradeGoods.getQuality() != null) {
                PhSysDictItem item = sysDictItemService.getDictItemByValue(DictConstant.CONDITION_TYPE,
                        cloudTradeGoods.getQuality().toString());

                if (item != null) {
                    goodsDetailVO.setQuality(item.getLabel());
                }
            }
        });

        //入库方式设置
        CompletableFuture<Void> inWayFuture = CompletableFuture.runAsync(() -> {
            if (cloudTradeGoods.getInWay() != null) {
                PhSysDictItem item = sysDictItemService.getDictItemByValue(DictConstant.GOTOWARE_TYPE,
                        cloudTradeGoods.getInWay().toString());

                if (item != null) {
                    goodsDetailVO.setInWay(item.getLabel());
                }
            }
        });

        //店铺设置
        CompletableFuture<Void> inventorySourceFuture = CompletableFuture.runAsync(() -> {
            if (cloudTradeGoods.getAccountId() != null) {
                PhSysDictItem item = sysDictItemService.getDictItemByValue(DictConstant.INVENTORY_SOURCE,
                        cloudTradeGoods.getAccountId().toString());

                if (item != null) {
                    goodsDetailVO.setAccountName(item.getLabel());
                }
            }
        });

        CompletableFuture.allOf(qualityFuture, inWayFuture, inventorySourceFuture).join();
        return goodsDetailVO;
    }

    @Override
    public CloudTradeGoodsDetailVO getCloudTradeGoodsDetailByChannelGoodsCode(String channelGoodsCode) {
        CloudTradeGoods cloudTradeGoods = this.getCloudTradeGoodsByChannelGoodsCode(channelGoodsCode);
        if (cloudTradeGoods == null) {
            throw new BusinessRuntimeException(ResponseCodeEnum.CLOUD_TRADE_GOODS_NOT_EXISTS_800100);
        }
        return this.getCloudTradeGoodsDetailById(cloudTradeGoods.getId());
    }

    @Override
    public IPage<CloudTradeGoods> getCloudTradeGoodsList(CloudTradeGoodsQuery cloudTradeGoodsQuery) {
        LambdaQueryWrapper<CloudTradeGoods> queryWrapper = Wrappers.lambdaQuery(CloudTradeGoods.class).
                like(StringUtils.isNotBlank(cloudTradeGoodsQuery.getChannelGoodsCode()),
                        CloudTradeGoods::getChannelGoodsCode,
                        cloudTradeGoodsQuery.getChannelGoodsCode())
                .like(StringUtils.isNotBlank(cloudTradeGoodsQuery.getInventoryName()),
                        CloudTradeGoods::getGoodsName,
                        cloudTradeGoodsQuery.getInventoryName())
                .eq(cloudTradeGoodsQuery.getInventorySourceId() != null,
                        CloudTradeGoods::getAccountId,
                        cloudTradeGoodsQuery.getInventorySourceId())
                .eq(cloudTradeGoodsQuery.getStatus() != null,
                        CloudTradeGoods::getStatus,
                        cloudTradeGoodsQuery.getStatus())
                .like(StringUtils.isNotBlank(cloudTradeGoodsQuery.getMaterialCode()),
                        CloudTradeGoods::getMaterialCode,
                        cloudTradeGoodsQuery.getMaterialCode())
                .orderByDesc(CloudTradeGoods::getUpdateTime);

        IPage<CloudTradeGoods> objectPage = new Page<>();
        objectPage.setCurrent(cloudTradeGoodsQuery.getPageIndex());
        objectPage.setSize(cloudTradeGoodsQuery.getPageSize());
        IPage<CloudTradeGoods> page = this.page(objectPage, queryWrapper);
        return page;
    }

    @Override
    public boolean changeCloudTradeGoodsStatus(Long id, Integer checkStatus) {
        boolean res = this.update(Wrappers.lambdaUpdate(CloudTradeGoods.class)
                .set(CloudTradeGoods::getStatus, checkStatus)
                .set(CloudTradeGoods::getCheckTime, new Date())
                .eq(CloudTradeGoods::getId, id)
        );
        if (res) {
            log.info("商品中心-更新商品状态成功: id:{}, checkStatus:{}", id, checkStatus);
        } else {
            log.error("商品中心-更新商品状态失败: id:{}, checkStatus:{}", id, checkStatus);
        }
        return res;
    }

    /**
     * 添加云商商品
     *
     * @param cloudTradeGoods
     * @return
     */
    @Override
    public boolean addCloudTradeGoods(CloudTradeGoods cloudTradeGoods) {
        return this.save(cloudTradeGoods);
    }

    /**
     * 更新云商商品
     *
     * @param cloudTradeGoods
     * @return
     */
    @Override
    public boolean updateCloudTradeGoods(CloudTradeGoods cloudTradeGoods) {
        return this.update(cloudTradeGoods, Wrappers.lambdaUpdate(CloudTradeGoods.class)
                .eq(CloudTradeGoods::getChannelGoodsCode, cloudTradeGoods.getChannelGoodsCode()));
    }

    @Override
    public boolean updateCloudTradeGoodsMaterialCode(String channelGoodsCode, String materialCode) {
        return this.update(Wrappers.lambdaUpdate(CloudTradeGoods.class)
                .set(CloudTradeGoods::getMaterialCode, materialCode)
                .eq(CloudTradeGoods::getChannelGoodsCode, channelGoodsCode));
    }

    /**
     * 根据渠道商品编码查询云商商品
     *
     * @param channelGoodsCode
     * @return
     */
    @Override
    public CloudTradeGoods getCloudTradeGoodsByChannelGoodsCode(String channelGoodsCode) {
        //查询商品
        return this.getOne(Wrappers.lambdaQuery(CloudTradeGoods.class)
                .eq(CloudTradeGoods::getChannelGoodsCode, channelGoodsCode));
    }

    @Override
    public boolean downShelf(String channelGoodsCode) {
        return this.update(Wrappers.lambdaUpdate(CloudTradeGoods.class)
                .set(CloudTradeGoods::getGoodsStatus, GoodsStatusEnum.PUT_SHELF.getCode())
                .eq(CloudTradeGoods::getChannelGoodsCode, channelGoodsCode));
    }

    @Override
    public boolean upShelf(String channelGoodsCode) {
        return this.update(Wrappers.lambdaUpdate(CloudTradeGoods.class)
                .set(CloudTradeGoods::getGoodsStatus, GoodsStatusEnum.ON_SHELF.getCode())
                .eq(CloudTradeGoods::getChannelGoodsCode, channelGoodsCode));
    }

    /**
     * 审核云商商品并分发数据至商品中心
     * @param checkDto
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public PhInventoryForCloudTradeDto checkCloudTradeGoodsAndDispatchDataToGoodsCenter(CloudTradeGoodsCheckDto checkDto) {
        CloudTradeGoods goods = this.getById(checkDto.getId());
        if (goods == null) {
            throw new BusinessRuntimeException(ResponseCodeEnum.CLOUD_TRADE_GOODS_NOT_EXISTS_800100);
        }
        //审核过的商品打回
        if (goods.getStatus() == CommonConstant.CLOUD_TRADE_GOODS_STATUS.PASS || (
                goods.getStatus() == NO_PASS && checkDto.getCheckStatus() == NO_PASS
        )) {
            throw new BusinessRuntimeException(CLOUD_TRADE_GOODS_CHECKED_OVER_800103);
        }

        //更新云商商品表状态
        boolean result = this.changeCloudTradeGoodsStatus(checkDto.getId(), checkDto.getCheckStatus());

        if (!result) {
            //更新云商商品表状态失败，打印警告日志
            log.error("云商商品添加审核日志失败: {}", checkDto.getId());
            throw new BusinessRuntimeException(CLOUD_TRADE_GOODS_UPDATE_STATUS_EXCEPTION_800101);
        }

        //添加审核日志
        addCheckLogs(checkDto);

        //审核未通过
        if (checkDto.getCheckStatus() == NO_PASS) {
            //回调审核信息到云商
            sendCheckResultToCloudTrade(checkDto, goods.getChannelGoodsCode());
            return null;
        }

        //审核通过后，分发数据至商品中心
        PhInventoryForCloudTradeDto inventoryForCloudTradeDto = cloudTradeCoreService.dispatchDataToGoodsCenter(goods);
        //回调审核信息到云商
        sendCheckResultToCloudTrade(checkDto, goods.getChannelGoodsCode());
        return inventoryForCloudTradeDto;
    }

    private void addCheckLogs(CloudTradeGoodsCheckDto checkDto) {
        LogsForTextAddDto textAddDto = new LogsForTextAddDto();
        textAddDto.setBusinessTable(BUSINESS_TYPE_CLOUD_TRADE);
        textAddDto.setRecordId(checkDto.getId());
        textAddDto.setOperator(checkDto.getOperator());
        textAddDto.setOperatorId(checkDto.getOperatorId());

        String text;
        if (NO_PASS == checkDto.getCheckStatus()) {
            text = String.format("审核不通过；未通过原因:%s", checkDto.getReason());
        }else {
            text = "审核通过";
        }
        textAddDto.setTextContent(text);
        operationRecordLogsCoreService.addTextAddOperationRecordLogs(textAddDto);
    }

    @Override
    public CloudTradeGoodsDetailV2VO getCloudTradeGoodsDetailByChannelGoodsCodeV2(String channelGoodsCode) {
        CloudTradeGoods cloudTradeGoods = this.getCloudTradeGoodsByChannelGoodsCode(channelGoodsCode);
        if (cloudTradeGoods == null) {
            throw new BusinessRuntimeException(ResponseCodeEnum.CLOUD_TRADE_GOODS_NOT_EXISTS_800100);
        }
        return this.getCloudTradeGoodsDetailByIdV2(cloudTradeGoods.getId());
    }

    private void sendCheckResultToCloudTrade(CloudTradeGoodsCheckDto checkDto, String channelGoodsCode) {
//        String url = "http://pre.partner.ponhu.cn/Releasenew/setExamineStatus";

        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        //头部类型
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
        //接口参数
        map.add("examineStatus", checkDto.getCheckStatus());
        map.add("code",channelGoodsCode);
        if(NO_PASS == checkDto.getCheckStatus()){
            map.add("examineRemarks", checkDto.getReason());
        }

        try {
            //构造实体对象
            HttpEntity<MultiValueMap<String, Object>> param = new HttpEntity<>(map, headers);
            //发起请求,服务地址，请求参数，返回消息体的数据类型
            ResponseEntity<String> response = restTemplate.postForEntity(CLOUD_TRADE_CHECK_RESULT_URL, param, String.class);
            //body
            String body = response.getBody();
            System.out.println("结果：" + body );
            Map result = JSONObject.parseObject(body, Map.class);
            if(result != null && CommonConstant.SUCCESS.toString().equals(Objects.toString(result.get("code"), null))){
                //成功
                log.info("回传审核状态至云商系统成功===>> channelGoodsCode:{}===>> {}",  channelGoodsCode, JSONObject.toJSONString(checkDto));
            }else{
                //回传失败
                log.error("回传审核状态至云商系统成功===>> channelGoodsCode:{}===>> {} ===> 返回结果:{}",
                        channelGoodsCode,
                        JSONObject.toJSONString(checkDto),
                        JSONObject.toJSON(body));
            }
        } catch (RestClientException e) {
            e.printStackTrace();
        }
    }
}




